Coverage Report

Created: 2024-12-19 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
D:\a\tools.proto\tools.proto\compiler\src\gen\base\message_common.rs
Line
Count
Source
1
// Copyright (c) 2024, BlockProject 3D
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification,
6
// are permitted provided that the following conditions are met:
7
//
8
//     * Redistributions of source code must retain the above copyright notice,
9
//       this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above copyright notice,
11
//       this list of conditions and the following disclaimer in the documentation
12
//       and/or other materials provided with the distribution.
13
//     * Neither the name of BlockProject 3D nor the names of its contributors
14
//       may be used to endorse or promote products derived from this software
15
//       without specific prior written permission.
16
//
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
use crate::compiler::message::{Field, FieldType, Referenced};
30
use crate::compiler::util::types::TypeMapper;
31
use crate::gen::base::map::TypePathMapper;
32
use crate::gen::base::message::Utilities;
33
use crate::gen::base::Error;
34
use crate::gen::template::Template;
35
use std::borrow::Cow;
36
37
pub struct MaybeOptional<'b, 'a, 'fragment, 'variable> {
38
    template: &'a Template<'fragment, 'variable>,
39
    function: &'b str,
40
    optional: bool
41
}
42
43
impl<'b, 'a, 'fragment, 'variable> MaybeOptional<'b, 'a, 'fragment, 'variable> {
44
121
    pub fn new(field: &Field, function: &'b str, template: &'a Template<'fragment, 'variable>) -> Self {
45
121
        Self {
46
121
            template,
47
121
            function,
48
121
            optional: field.optional
49
121
        }
50
121
    }
51
52
121
    pub fn gen<'c>(self, type_name: impl Into<Cow<'c, str>>) -> Result<Cow<'c, str>, Error> where 'a: 'c {
53
121
        if self.optional {
  Branch (53:12): [True: 5, False: 37]
  Branch (53:12): [True: 11, False: 58]
  Branch (53:12): [True: 0, False: 10]
  Branch (53:12): [Folded - Ignored]
54
16
            self.template
55
16
                .scope()
56
16
                .var("msg_type", type_name)
57
16
                .render(self.function, &["option"])
58
16
                .map(|v| v.into())
59
16
                .map_err(Error::Codec)
60
        } else {
61
105
            Ok(type_name.into())
62
        }
63
121
    }
64
}
65
66
121
pub fn generate_field_type_inline<'a, U: Utilities, T: TypeMapper>(
67
121
    field: &'a Field,
68
121
    template: &'a Template,
69
121
    type_path_map: &'a TypePathMapper<T>,
70
121
    function: &str
71
121
) -> Result<Cow<'a, str>, Error> {
72
121
    let optional = MaybeOptional::new(field, function, template);
73
121
    let msg_type = match &field.ty {
74
10
        FieldType::Fixed(ty) => optional.gen(U::get_value_type_inline(field.endianness, ty.ty)),
75
29
        FieldType::Ref(v) => match v {
76
24
            Referenced::Struct(v) => optional.gen(type_path_map.get(v)),
77
5
            Referenced::Message(v) => optional.gen(type_path_map.get(v)),
78
        },
79
26
        FieldType::Buffer => optional.gen(template.scope().render(function, &["buffer"]).map_err(Error::Codec)
?0
),
80
9
        FieldType::SizedBuffer(v) => optional.gen(
81
9
            template
82
9
                .scope()
83
9
                .var("codec", U::get_value_type(field.endianness, v.ty))
84
9
                .render(function, &["sized_buffer"])
85
9
                .map_err(Error::Codec)
?0
86
        ),
87
8
        FieldType::FixedContainer(v) => optional.gen(
88
8
            template
89
8
                .scope()
90
8
                .var("codec", U::get_value_type(field.endianness, v.ty))
91
8
                .var("type_name", type_path_map.get(&v.item_type))
92
8
                .render(function, &["fixed_container"])
93
8
                .map_err(Error::Codec)
?0
94
        ),
95
13
        FieldType::Union(v) => optional.gen(type_path_map.get(&v.r)),
96
19
        FieldType::Container(v) => match v.nested {
97
15
            false => optional.gen(
98
15
                template
99
15
                    .scope()
100
15
                    .var("codec", U::get_value_type(field.endianness, v.ty))
101
15
                    .var("type_name", type_path_map.get(&v.item_type))
102
15
                    .render(function, &["unsized_container"])
103
15
                    .map_err(Error::Codec)
?0
104
            ),
105
4
            true => optional.gen(
106
4
                template
107
4
                    .scope()
108
4
                    .var("codec", U::get_value_type(field.endianness, v.ty))
109
4
                    .var("type_name", type_path_map.get(&v.item_type))
110
4
                    .render(function, &["container"])
111
4
                    .map_err(Error::Codec)
?0
112
            ),
113
        },
114
0
        FieldType::Payload => optional.gen(template.scope().render(function, &["payload"]).map_err(Error::Codec)?),
115
7
        FieldType::SizedContainer(v) => optional.gen(
116
7
            template
117
7
                .scope()
118
7
                .var("codec", U::get_value_type(field.endianness, v.ty))
119
7
                .var("type_name", type_path_map.get(&v.item_type))
120
7
                .var("size_codec", U::get_value_type(field.endianness, v.size_ty))
121
7
                .render(function, &["sized_container"])
122
7
                .map_err(Error::Codec)
?0
123
        ),
124
    };
125
121
    msg_type
126
121
}